/*
 * Copyright © 2017 eqxiu.com 北京中网易企秀科技有限公司  All rights reserved.
 */

package cn.hermit.nio.http.server;

import cn.hermit.nio.core.RequestHandler;
import cn.hermit.nio.http.Http;
import cn.hermit.nio.server.ServerDataEvent;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author JackGao 高建国
 * @description //TODO 设计说明
 * @date 29/5/2017
 */
public class HttpRequestHandler implements RequestHandler, Http {

    private static final Logger logger = Logger.getLogger(HttpRequestHandler.class.getName());

    private volatile boolean enableCors = false;

    private volatile HttpRouter router;

    private ResourceHttpHandler resourceHttpHandler = new ResourceHttpHandler();

    @Override
    public void handle(ServerDataEvent dataEvent) {
        long startTime = System.currentTimeMillis();

        HttpRequestParser requestParser = new HttpRequestParser();

        HttpResponse response = new HttpResponse();
        try {
            if (requestParser.appendSegment(dataEvent.data)) {

                System.out.println(new String(dataEvent.data));

                HttpRequest request = requestParser.getHttpRequest();
                HttpHandler handler = router.route(request);
                if(handler == null) {
                    handler = resourceHttpHandler;
                }
                response.addHeader(CONNECTION, KEEP_ALIVE);
                if (enableCors) {
                    response.addHeader("Access-Control-Allow-Origin", "*");
                    response.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, OPTIONS");
                    response.addHeader("Access-Control-Allow-Headers", "Content-Type, api_key, Authorization");
                }
                handler.handle(request, response);

                // data is prepared, send out to the client
                System.out.println(new String(response.getHeaderBytes()));
                dataEvent.server.send(dataEvent.socket, response.getHeaderBytes());
                if (response.getBody() != null)
                    dataEvent.server.send(dataEvent.socket, response.getBody());

            }
        } catch (Exception e) {
            e.printStackTrace();
            // any other, it's a 505 error
            response.addHeader(CONTENT_LENGTH, 0);
            response.setStatus(SERVER_ERROR_500);
            dataEvent.server.send(dataEvent.socket, response.getHeaderBytes());
            logger.log(Level.SEVERE, "505 error", e);
        } finally {
            logger.log(Level.INFO, "Total Time: " + (System.currentTimeMillis() - startTime) + "ms");
        }

    }

    public void handleStaticResource(HttpRequest request, HttpResponse response) {

    }

    public HttpRouter getRouter() {
        return router;
    }

    public void setRouter(HttpRouter router) {
        this.router = router;
    }

    public void setStaticRoot(String staticRoot) {
        resourceHttpHandler.setStaticRoot(staticRoot);
    }

    public void enableCors(boolean enableCors) {
        this.enableCors = enableCors;
    }
}